home *** CD-ROM | disk | FTP | other *** search
- // $VER: DirDiver 1.1.0
- //
- // Purpose: traverse a directory structure
- // History: 05-06-1998 Creation CDM
- // 13-06-1998 Added BOOL icase switch CDM
- // 17-04-1999 Changed for FBackNG CDM
- // 24-04-1999 Added file functions CDM
- // 26-04-1999 Added time functions CDM
- // 30-04-1999 Added Handler, XPK CDM
- // 14-05-1999 Fixed dest. path creation CDM
- // MIRROR reports files in debug CDM
- // 15-05-1999 MIRROR enabled CDM
- // Priority option CDM
- // 20-05-1999 MIRROR path creation fixed CDM
- // MIRROR check existenz only CDM
- // 30-10-1999 Added DirCleaner() CDM
- // 10-12-1999 Added noarch option CDM
- //
- // (C)1999 Visionary Software - FREEWARE
-
- #ifndef FBACKNG_H
- #include "fbackng.h"
- #endif
- #include "dirdiver.h"
- #include "support.h"
-
- /* Xpk stuff */
- char errbuf[XPKERRMSGSIZE+1];
-
- // log stuff
- char errormsg[256];
-
- // Xpk func
- long __asm __saveds chunkfunc(register __a1 struct XpkProgress *prog)
- {
- sprintf(errormsg,"\r%4s: %-9s (%6d bytes, %3d%% done, %2d%% CF, %6d cps) ",
- prog->xp_PackerName, prog->xp_Activity, prog->xp_ULen, prog->xp_Done,
- prog->xp_CF, prog->xp_Speed);
- if(prog->xp_Type == XPKPROG_END)
- {
- strcat(errormsg,"\n");
- check_write_log(NULL);
- }
-
- if(optval.val_verbose != OUT_QUIET)
- {
- if(prog->xp_Type == XPKPROG_END)
- {
- printf("%s\n",errormsg);
- }
- }
- return 0;
- }
-
- struct Hook chunkhook = {{0},chunkfunc};
-
- struct TagItem tags[] = {
- XPK_InName, (long)NULL ,
- XPK_OutName, (long)NULL ,
- XPK_Ignore, (long)0 ,
- XPK_NoClobber, (long)TRUE ,
- XPK_GetError, (long)errbuf,
- XPK_ChunkHook, (long)&chunkhook,
- TAG_DONE};
-
- // check if user needs a log and write a message to it if active
- void check_write_log(char *custom)
- {
- int err;
-
- if(optflg.opt_log)
- {
- if(custom!=NULL)
- sprintf(errormsg,"%s",custom);
-
- if((err=put_LogOneMsg(optval.val_log,errormsg))!=DD_OK)
- {
- fprintf(stderr,"%s: fatal: cannot write to log %s (%d)\n",optval.val_log,err);
- exit(1);
- }
- }
- }
-
- // check if directory exists
- int Check_Dir(char *name)
- {
- DIR *dfd;
-
- dfd = opendir(name);
- if(dfd == NULL)
- return(FALSE);
- closedir(dfd);
-
- return(TRUE);
- }
-
- // check if file exists and is readable
- int Check_File(char *name)
- {
- if((access(name,F_OK))==0)
- return(TRUE);
-
- return(FALSE);
- }
-
- int Copy_File(char *infile,char *outfile)
- {
- FILE *in,*out;
- char *buf;
- int i;
-
- if((buf=malloc(BUF_SIZE))==NULL)
- return(DD_CALLOC);
-
- if((in=fopen(infile,"r"))==NULL)
- {
- free(buf);
- return(DD_OPENSOURCE);
- }
-
- if((out=fopen(outfile,"wt"))==NULL)
- {
- fclose(in);
- free(buf);
- return(DD_OPENDEST);
- }
-
- while(i=fread(buf,1,BUF_SIZE,in))
- if(fwrite(buf,1,i,out)!=i)
- break;
-
- i=(ferror(in)||ferror(out))?DD_COPY:DD_OK;
-
- fclose(in);
- fclose(out);
- free(buf);
-
- return(i);
- }
-
- // checks dest dir and clones creation of path
- int Clone_Dir(char *path)
- {
- int op,np;
- char res[512],target[512];
-
- res[0]=0;
-
- np = SplitName(path,':',res,0,512);
-
- if(np!=-1)
- {
- strcat(res,":");
- if(!(Check_Dir(res)))
- return(DD_VOLERROR);
- }
- else
- np = 0;
-
- strcpy(target,res);
-
- op = np;
- while(op!=-1)
- {
- np = SplitName(path,'/',res,op,512);
-
- sprintf(target,"%s%s",target,res);
- if(!(Check_Dir(target)))
- mkdir(target);
-
- if(np!=-1)
- strcat(target,"/");
- op = np;
- }
-
- return(DD_OK);
- }
-
- // checks paths
- void Check_Slash(char *path)
- {
- char *p,*q;
- int found,i;
- char res[512];
-
- found = 0;
- p = path;
- q = NULL;
-
- for(i=0;*p != 0; q=p,p++)
- {
- if(*p == '/')
- {
- found++;
- if(*q==':')
- found = 2;
- }
- else
- found = 0;
-
- if(found<2)
- {
- res[i] = *p;
- i++;
- }
- else
- found=0;
- }
- res[i]=0;
- strcpy(path,res);
- }
-
- // adds delete flag of file
- int Set_Delete_File(char *name)
- {
- int error;
-
- error = DD_OK;
-
- chmod(name,S_IREAD|S_IWRITE|S_IDELETE);
- return(error);
- }
-
- // adds archive flag of file
- int Set_Archive_File(char *name)
- {
- BPTR lock;
- struct FileInfoBlock fib;
- int error;
-
- error = DD_OK;
-
- if((lock=Lock(name,ACCESS_READ))==NULL)
- return(DD_LOCKFILE);
-
- if((Examine(lock,&fib)))
- {
- UnLock(lock);
- fib.fib_Protection |= FIBF_ARCHIVE;
- if(!(SetProtection((STRPTR)name,fib.fib_Protection)))
- error = DD_ARCHFILE;
- }
- else
- {
- UnLock(lock);
- error = DD_EXFILE;
- }
- return(error);
- }
-
- // clones flags of file
- int Clone_Protect_File(char *name, char *uit)
- {
- BPTR lock;
- struct FileInfoBlock fib;
- int error;
-
- error = DD_OK;
-
- if((lock=Lock(name,ACCESS_READ))==NULL)
- return(DD_LOCKFILE);
-
- if((Examine(lock,&fib)))
- {
- UnLock(lock);
- if(!(SetProtection((STRPTR)uit,fib.fib_Protection)))
- error = DD_PROTFILE;
- }
- else
- {
- UnLock(lock);
- error = DD_EXFILE;
- }
- return(error);
- }
-
- // clone date to destination file
- int Clone_DateStamp_File(char *name, char *uit)
- {
- BPTR lock;
- struct FileInfoBlock fib;
- int error;
-
- error = DD_OK;
-
- if((lock=Lock(name,ACCESS_READ))==NULL)
- return(DD_LOCKFILE);
-
- if((Examine(lock,&fib)))
- {
- UnLock(lock);
- if(!(SetFileDate((STRPTR)uit,&fib.fib_Date)))
- error = DD_DATEFILE;
- }
- else
- {
- UnLock(lock);
- error = DD_EXFILE;
- }
- return(error);
- }
-
- int System_DateStamp_File(char *name)
- {
- struct DateStamp *tijd;
- int error;
-
- error = DD_OK;
-
- tijd = __timecvt(time(NULL));
-
- if(!(SetFileDate((STRPTR)name,tijd)))
- error = DD_SYSTFILE;
-
- return(error);
- }
-
- // clone comment to destination file
- int Clone_Comment_File(char *name, char *uit)
- {
- BPTR lock;
- struct FileInfoBlock fib;
- int error;
-
- error = DD_OK;
-
- if((lock=Lock(name,ACCESS_READ))==NULL)
- return(DD_LOCKFILE);
-
- if((Examine(lock,&fib)))
- {
- UnLock(lock);
- if(!(SetComment((STRPTR)uit,(STRPTR)&fib.fib_Comment)))
- error = DD_COMMFILE;
- }
- else
- {
- UnLock(lock);
- error = DD_EXFILE;
- }
- return(error);
- }
-
- // delete a file
- int Delete_File(char *thefile)
- {
- int error;
-
- if((error=Set_Delete_File(thefile))!=DD_OK)
- return(error);
-
- if((error=remove(thefile))!=0)
- return(DD_DELFILE);
-
- return(DD_OK);
- }
-
- // delete a dir
- int Delete_Dir(char *thedir)
- {
- int error;
-
- if((error=rmdir(thedir))!=0)
- return(DD_DELDIRS);
-
- return(DD_OK);
- }
-
- // pack a file
- int Pack_File(char *in,char *out,char *packer)
- {
- int res;
-
- tags[0].ti_Data = (long)in;
- tags[1].ti_Data = (long)out;
- tags[2].ti_Tag = XPK_PackMethod;
- tags[2].ti_Data = (long)packer;
- res = XpkPack(tags);
-
- return(res);
- }
-
- // get flags and convert to displayable string
- void WhichFlags(ULONG flg,char *res)
- {
- char temp[6];
-
- if((flg&FIBF_ARCHIVE)==0)
- temp[0] = '-';
- else
- temp[0] = 'a';
-
- if((flg&FIBF_READ)!=0)
- temp[1] = '-';
- else
- temp[1] = 'r';
-
- if((flg&FIBF_WRITE)!=0)
- temp[2] = '-';
- else
- temp[2] = 'w';
-
- if((flg&FIBF_EXECUTE)!=0)
- temp[3] = '-';
- else
- temp[3] = 'e';
-
- if((flg&FIBF_DELETE)!=0)
- temp[4] = '-';
- else
- temp[4] = 'd';
-
- temp[5] = 0;
-
- strcpy(res,temp);
- }
-
- BOOL Compare_Dates(STRPTR name)
- {
- BPTR lock;
- LONG r;
- struct FileInfoBlock fib;
-
- if((lock=Lock(name,ACCESS_READ))==NULL)
- return(FALSE);
- if((Examine(lock,&fib)))
- {
- UnLock(lock);
- if(optflg.opt_before)
- {
- r = CompareDates(&dt_Before.dat_Stamp,&fib.fib_Date);
- if(r>0)
- return(FALSE);
- else
- return(TRUE);
- }
- if(optflg.opt_after)
- {
- r = CompareDates(&dt_After.dat_Stamp,&fib.fib_Date);
- if(r>0)
- return(TRUE);
- else
- return(FALSE);
- }
- }
- else
- {
- UnLock(lock);
- return(FALSE);
- }
- return(FALSE);
- }
-
- int Handle_Backup_File(char *infile,char *outfile)
- {
- int error;
-
- if(Check_File(outfile))
- {
- error = Delete_File(outfile);
- if(error!=DD_OK)
- return(error);
- }
-
- if(optflg.opt_compress)
- {
- error=Pack_File(infile,outfile,optval.val_compress);
-
- if(error!=0) // if error pack, then just copy
- error=Copy_File(infile,outfile);
- }
- else
- error=Copy_File(infile,outfile);
-
- if(error==DD_OK)
- {
- if((error=Clone_Protect_File(infile,outfile))==DD_OK)
- {
- if(optflg.opt_noarch) // V1.2.0
- error = DD_OK;
- else
- error=Set_Archive_File(infile);
-
- if(error != DD_OK)
- {
- if(!optflg.opt_nonotes)
- {
- if((error=Clone_Comment_File(infile,outfile))==DD_OK)
- {
- if(optflg.opt_touch)
- error=System_DateStamp_File(outfile);
- else
- error=Clone_DateStamp_File(infile,outfile);
- }
- }
- }
- }
- }
-
- return(error);
- }
-
- int Handle_Mirror_File(char *infile,char *outfile)
- {
- int error=DD_OK;
-
- if(!(Check_File(outfile)))
- {
- error = Delete_File(infile);
- if(error!=DD_OK)
- return(error);
- prc_files++;
- return(DD_DELETED);
- }
-
- return(error);
- }
-
- // backup/mirror engine
- int __aligned __saveds DirDiver(char *root,int mode)
- {
- BOOL more;
- BOOL valid;
- BPTR lock;
- struct ExAllControl *eac;
- struct ExAllData *ead;
- struct ExAllData *tmp;
- UBYTE templat[256];
- UBYTE sname[512],dname[512],tname[512],tdir[512];
- char flags[6];
- int result;
-
- if(!(lock = Lock(root, ACCESS_READ))) return(DD_LOCK); // get lock on FS
-
- if(!(tmp = calloc(1,4096)))
- {
- UnLock(lock);
- return(DD_CALLOC);
- }
-
- ParsePatternNoCase(optval.val_pattern, &templat[0], 256);
-
- if(!(eac = AllocDosObject(DOS_EXALLCONTROL, NULL)))
- {
- free(tmp);
- UnLock(lock);
- return(DD_ALLOCDOS);
- }
-
- sprintf(errormsg,"[Searching Directory ] %s\n",root);
- check_write_log(NULL);
- if(optval.val_verbose > OUT_NORMAL)
- {
- printf("%s",errormsg);
- }
-
- eac->eac_LastKey = 0;
-
- tot_direc++;
-
- // get files
- do {
- Chk_Abort();
-
- more = ExAll(lock, tmp, 4096, ED_COMMENT, eac);
-
- if(eac->eac_Entries != 0)
- {
- ead = tmp;
-
- if(mode == BACKUP_PHASE)
- {
- if((strcmp(root,optval.val_source))!=0)
- strmid(root,tname,strlen(optval.val_source)+1,strlen(root));
- else
- strcpy(tname,"");
- }
- else // MIRROR_PHASE
- {
- if((strcmp(root,optval.val_dest))!=0)
- strmid(root,tname,strlen(optval.val_dest)+1,strlen(root));
- else
- strcpy(tname,"");
- }
-
-
- if(optval.val_verbose == OUT_DEBUG)
- {
- sprintf(errormsg,"[Found Directory Entries ] %ld\n",eac->eac_Entries);
- check_write_log(NULL);
- printf("%s",errormsg);
- }
-
- do {
- Chk_Abort();
-
- if(ead->ed_Type < 0) // a file
- {
-
- tot_files++;
-
- if((MatchPatternNoCase(&templat[0], ead->ed_Name)))
- {
- strcpy(sname,root);
- AddPart(sname,ead->ed_Name,512);
-
-
- if(mode == BACKUP_PHASE)
- {
-
- WhichFlags(ead->ed_Prot,flags);
-
- if(optval.val_verbose == OUT_DEBUG)
- {
- sprintf(errormsg,"[Protection Flags ] %s\n",flags);
- check_write_log(NULL);
- printf("%s",errormsg);
- }
-
- sprintf(errormsg,"[Matched Filename ] %s\n",sname);
- check_write_log(NULL);
- if(optval.val_verbose > OUT_NORMAL)
- {
- printf("%s",errormsg);
- }
-
-
- if((flags[0]=='a' && optflg.opt_every)||flags[0]=='-')
- {
- if(optflg.opt_before || optflg.opt_after)
- valid = Compare_Dates(sname);
- else
- valid = TRUE;
-
- if(valid)
- {
- prc_files++;
-
- sprintf(errormsg,"[Backup Filename ] %s\n",sname);
- check_write_log(NULL);
- if(optval.val_verbose > OUT_QUIET)
- printf("%s",errormsg);
-
- strcpy(dname,optval.val_dest); // dest root
- AddPart(dname,tname,512); // dest path
- Check_Slash(dname);
- strcpy(tdir,dname); // save dest path
-
- AddPart(dname,ead->ed_Name,512); // dest file
-
- if(optval.val_verbose == OUT_DEBUG)
- {
- sprintf(errormsg,"[Source, Destination ] %s, %s\n",sname,dname);
- check_write_log(NULL);
- printf("%s",errormsg);
- }
-
- if(!optflg.opt_simulate)
- {
- if((result = Clone_Dir(tdir))!=DD_OK)
- {
- FreeDosObject(DOS_EXALLCONTROL, eac);
- free(tmp);
- UnLock(lock);
- return(result);
- }
-
- if((result = Handle_Backup_File(sname,dname))!=DD_OK)
- {
- FreeDosObject(DOS_EXALLCONTROL, eac);
- free(tmp);
- UnLock(lock);
- return(result);
- }
- }
- }
- }
- }
- else // MIRROR PHASE
- {
-
- strcpy(dname,optval.val_source); // dest root
- AddPart(dname,tname,512); // dest path
- Check_Slash(dname);
- strcpy(tdir,dname); // save dest path
-
- AddPart(dname,ead->ed_Name,512); // dest file
-
- if(optval.val_verbose == OUT_DEBUG)
- {
- sprintf(errormsg,"[Source, Destination ] %s, %s\n",sname,dname);
- check_write_log(NULL);
- printf("%s",errormsg);
- }
-
- if(!optflg.opt_simulate)
- {
- if((result = Handle_Mirror_File(sname,dname))!=DD_OK)
- {
- if(result != DD_DELETED)
- {
- FreeDosObject(DOS_EXALLCONTROL, eac);
- free(tmp);
- UnLock(lock);
- return(result);
- }
- }
- if(result == DD_DELETED)
- {
- sprintf(errormsg,"[Delete Filename ] %s\n",sname);
- check_write_log(NULL);
- if(optval.val_verbose > OUT_QUIET)
- {
- printf("%s",errormsg);
- }
- }
- }
- }
- }
- }
-
- ead = ead->ed_Next;
- } while(ead);
- }
- } while(more);
-
- more = FALSE;
-
- eac->eac_LastKey = 0;
-
- if(optflg.opt_recursive)
- {
- // get directories
- do {
- Chk_Abort();
-
- more = ExAll(lock, tmp, 4096, ED_SIZE, eac);
-
- if(eac->eac_Entries == 0) continue;
-
- ead = tmp;
-
- do {
- Chk_Abort();
-
- if(ead->ed_Type > 0) // a directory
- {
- strcpy(sname, root);
- AddPart(sname, ead->ed_Name, 512);
-
- result = DirDiver(sname,mode);
-
- if(result!=DD_OK)
- {
- if(eac) FreeDosObject(DOS_EXALLCONTROL, eac);
- if(tmp) free(tmp);
- if(lock) UnLock(lock);
- return(result);
- }
- }
-
- ead = ead->ed_Next;
- } while(ead);
- } while(more);
- }
-
- // clean up
- if(eac) FreeDosObject(DOS_EXALLCONTROL, eac);
- if(tmp) free(tmp);
- if(lock) UnLock(lock);
-
- return(DD_OK);
- }
-
- // cleaner engine
- int __aligned __saveds DirCleaner(char *root)
- {
- BOOL more;
- BOOL empty;
- BPTR lock;
- struct ExAllControl *eac;
- struct ExAllData *ead;
- struct ExAllData *tmp;
- UBYTE sname[512];
- int result;
-
- if(!(lock = Lock(root, ACCESS_READ))) return(DD_LOCK); // get lock on FS
-
- if(!(tmp = calloc(1,4096)))
- {
- UnLock(lock);
- return(DD_CALLOC);
- }
-
- if(!(eac = AllocDosObject(DOS_EXALLCONTROL, NULL)))
- {
- free(tmp);
- UnLock(lock);
- return(DD_ALLOCDOS);
- }
-
- sprintf(errormsg,"[Searching Directory ] %s\n",root);
- check_write_log(NULL);
- if(optval.val_verbose > OUT_NORMAL)
- {
- printf("%s",errormsg);
- }
-
- eac->eac_LastKey = 0;
- empty = FALSE;
- tot_direc++;
- more = FALSE;
-
- if(optflg.opt_recursive)
- {
- // get directories
- do {
- Chk_Abort();
-
- more = ExAll(lock, tmp, 4096, ED_SIZE, eac);
-
- if(eac->eac_Entries == 0)
- {
- empty = TRUE;
- continue;
- }
-
- ead = tmp;
-
- do {
- Chk_Abort();
-
- if(ead->ed_Type > 0) // a directory
- {
- strcpy(sname, root);
- AddPart(sname, ead->ed_Name, 512);
-
- result = DirCleaner(sname);
-
- if(result!=DD_OK)
- {
- if(eac) FreeDosObject(DOS_EXALLCONTROL, eac);
- if(tmp) free(tmp);
- if(lock) UnLock(lock);
- return(result);
- }
- }
-
- ead = ead->ed_Next;
- } while(ead);
- } while(more);
- }
-
- // clean up
- if(eac) FreeDosObject(DOS_EXALLCONTROL, eac);
- if(tmp) free(tmp);
- if(lock) UnLock(lock);
-
- if(empty)
- {
- result = Delete_Dir(root);
- if(result!=DD_OK)
- return(result);
- del_dirs++;
- sprintf(errormsg,"[Deleted Directory ] %s\n",root);
- check_write_log(NULL);
- if(optval.val_verbose > OUT_NORMAL)
- {
- printf("%s",errormsg);
- }
- }
- return(DD_OK);
- }
- // end
-